package tt.com.cremationmanager.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tt.com.common.enums.Status;
import tt.com.common.model.*;
import tt.com.common.util.CommonResult;
import tt.com.common.util.PageUtil;
import tt.com.cremationmanager.mapper.CrematesMapper;
import tt.com.cremationmanager.service.CrematesService;
import tt.com.depositmessage.vo.DeadMessageVo;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;

@Service
public class CrematesImpl extends ServiceImpl<CrematesMapper, Cremate> implements CrematesService {

    @Autowired
    private CrematesMapper cremateMapper;

    /**
     * 展示火化业务信息列表
     * @param i (0表示展示已火化信息列表，1表示展示未火化信息列表)
     * @param pageUtil
     * @return
     */
    @Override
    public CommonResult showCremateMessage(String i, PageUtil pageUtil) {
        List<Cremate> list = baseMapper.selectList(null);
        if (list.size()<=0){
            return CommonResult.buildR(Status.OK,"列表信息为空");
        }
        pageUtil.setTotalSize(list.size());
        //cremate_status为火化办理状态
        //0为未火化  1为已火化
        IPage<Cremate> page = new Page<>(pageUtil.getPageIndex(),pageUtil.getPageSize());
        QueryWrapper<Cremate> qw = new QueryWrapper<>();
        if (i.equals("0")){
            qw.eq("cremate_status",1).eq("data_status",1);
        }else {
            qw.eq("cremate_status",0).eq("data_status",1);
        }
        IPage<Cremate> page1 = baseMapper.selectPage(page,qw);
        pageUtil.setData(page1);

        return CommonResult.buildR(Status.OK,"已展示查询信息",pageUtil);
    }

    /**
     * 查找火化业务信息
     * @param cremate
     * @return
     */
    @Override
    public CommonResult selectCremateMessage(Cremate cremate, PageUtil pageUtil) {
        List<Cremate> list = baseMapper.selectList(null);
        pageUtil.setTotalSize(list.size());

        List<Cremate> list1 = cremateMapper.selectCremateMessage(cremate,pageUtil);
        pageUtil.setData(list1);
        return  CommonResult.buildR(Status.OK,"查找成功",pageUtil);
    }

    /**
     * 修改火化业务信息
     * @param cremate
     * @return
     */
    @Override
    public CommonResult updateCremateMessage(Cremate cremate) {
        if (baseMapper.updateById(cremate)==1){
            return CommonResult.buildR(Status.OK,"数据更新成功");
        }else {
            return CommonResult.buildR(Status.DEFAULT,"数据更新失败");
        }
    }

    /**
     * 新增火化业务信息
     * @param cremate
     * @return
     */
    @Override
    public CommonResult insertCremateMessage(Cremate cremate) {
        List<Cremate> list = baseMapper.selectList(null);
        cremate.setId((list.size()+1)+"");
        cremate.setCremateStatus(1);
        cremate.setCreateTime(new Date());
        cremate.setLastUpdateTime(new Date());
        cremate.setDataStatus(1);
        if (baseMapper.insert(cremate)==1){
            return CommonResult.buildR(Status.OK,"数据已添加");
        }else {
            return CommonResult.buildR(Status.DEFAULT,"数据添加失败");
        }
    }

    /**
     * 伪删除火化业务信息
     * @param cremate
     * @return
     */
    @Override
    public CommonResult deleteCremateMessage(Cremate cremate) {
        cremate.setDataStatus(0);
        if (baseMapper.updateById(cremate)==1){
            return CommonResult.buildR(Status.OK,"数据已删除！");
        }else {
            return CommonResult.buildR(Status.OK,"数据删除失败！");
        }
    }

    /**
     * 刷新火化业务信息列表
     * @return
     */
    @Override
    public CommonResult refreshCremateMessage(PageUtil pageUtil) {
        List<Cremate> list = baseMapper.selectList(null);
        //判断数据库中是否还有数据  无则直接返回
        if (list.size() <= 0){
            return CommonResult.buildR(Status.OK,"列表信息为空");
        }
        pageUtil.setTotalSize(list.size());
        IPage<Cremate> page = new Page<>(pageUtil.getPageIndex(),pageUtil.getPageSize());
        QueryWrapper<Cremate> qw = new QueryWrapper<>();
        qw.ne("data_status",0);
        IPage<Cremate> page1 = baseMapper.selectPage(page,qw);
        pageUtil.setData(page1);
        return CommonResult.buildR(Status.OK,"刷新成功",pageUtil);
    }

    /**
     * 查询所有空闲火化炉
     * @return
     */
    @Override
    public CommonResult selectFreeCreateStove() {
        List<CremateStove> list = cremateMapper.selectFreeCreateStove();
        if (list.size()<=0){
            return CommonResult.buildR(Status.OK,"查询数据为空");
        }else {
            return CommonResult.buildR(Status.OK,"查询成功",list);
        }
    }

    /**
     * 设置火化炉编号，火化开始
     * @param cremate
     * @return
     */
    @Override
    public CommonResult startCreate(Cremate cremate) {
        if (cremate.getCremateStoveId()=="" || cremate.getCremateStoveId()==null){
            return CommonResult.buildR(Status.DEFAULT,"未分配火化炉");
        }
        cremate.setCreateTime(new Date());
        if (baseMapper.updateById(cremate) == 1){
            if (cremateMapper.updateCreateStoveStatusBy2(cremate.getCremateStoveId())==1){
                return CommonResult.buildR(Status.OK,"开始火化");
            }else {
                //回滚事务
                return CommonResult.buildR(Status.OK,"开始火化");
            }
        }else {
            return CommonResult.buildR(Status.OK,"启动火化失败");
        }
    }

    /**
     * 火化结束,设置火化炉状态为空闲
     * @param cremate
     * @return
     */
    @Override
    public CommonResult stopCreate(Cremate cremate) {
        Cremate c = baseMapper.selectById(cremate.getId());
        c.setFinishTime(new Date());
        c.setCremateStatus(0);
        //先将被使用的火化炉状态设置为空闲
        //在将火化信息中 取消分配的火化炉
        if (cremateMapper.updateCreateStoveStatusBy1(c.getCremateStoveId())==1){
            c.setCremateStoveId("");
            if (baseMapper.updateById(c) == 1){
                return CommonResult.buildR(Status.OK,"火化结束");
            }else {
                //回滚事务
                return CommonResult.buildR(Status.DEFAULT,"开始火化");
            }
        }else {
            return CommonResult.buildR(Status.OK,"执行错误");
        }



    }

    /**
     * 设定骨灰收敛时间
     * @return
     */
    @Override
    public CommonResult convergenceBone(Cremate cremate) {
        Dead dead = new Dead();
        dead.setId(cremate.getDeadId());
        dead.setConvergenceTime(new Date());
        if (cremateMapper.updateConvergenceTime(dead)==1){
            return CommonResult.buildR(Status.OK,"已登记骨灰领取时间");
        }else {
            return CommonResult.buildR(Status.DEFAULT,"登记失败");
        }
    }

    /**
     * 打印寄存证
     * @param i 服务id（1为骨灰盒，2为影雕刻字，3为铺金盖银）
     * @return
     */
    @Override
    public CommonResult serviceReceipt(HttpServletResponse response, int i) {
        String service = null;
        switch (i){
            case 1:
                service = "骨灰盒";
                break;
            case 2:
                service = "影雕刻字";
                break;
            case 3:
                service = "铺金盖银";
                break;
            default:
                return CommonResult.buildR(Status.DEFAULT,"没有该服务，请重新输入");
        }
        List<YxCommonServeProviders> list = cremateMapper.selectService(service);
        YxCommonServeProviders server = null;
        for (YxCommonServeProviders item:list){
            server = item;
        }

        // 模板路径
        URL path = this.getClass().getResource("/printTemplate/jifang.pdf");
        // 生成文件路径
        String filename = server.getName()+"服务收款收据.pdf";
        //根据模板填入信息
        Map<String, Object> datas = new HashMap<>();
        datas.put("name", server.getName());
        datas.put("price", server.getPrice());
        datas.put("time", new Date());

        //调用打印PDF的方法
        CommonResult result = printPdf(response,path,filename,datas);
        return result;
    }

    /**
     * 打印PDF
     * @param response
     * @param path 模板文件路径
     * @param filename 文件保存路径
     * @param datas 填入PDF表单中的数据
     * @return
     */
    public CommonResult printPdf(HttpServletResponse response,URL path,String filename,Map<String, Object> datas){
        PdfReader reader;
        OutputStream os = null;
        ByteArrayOutputStream baos = null;
        PdfStamper stamper;

        try {
            os = response.getOutputStream();
            // 读入pdf表单
            reader = new PdfReader(path);
            baos = new ByteArrayOutputStream();
            // 根据表单生成一个新的pdf
            stamper = new PdfStamper(reader, baos);
            // 获取pdf表单
            AcroFields formTexts = stamper.getAcroFields();

            // 设置字体(这里设置为系统字体，你也可以引入其他的字体)，不设置很可能，中文无法显示。
            BaseFont bf = BaseFont.createFont("C:/WINDOWS/Fonts/SIMSUN.TTC,1",
                    BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            formTexts.addSubstitutionFont(bf);

            // 数据查询后，值的植入 强烈推荐键值方式，其他方式很容易混
            Set<String> keySet =  datas.keySet();
            for (String key : keySet) {
                formTexts.setField(key, datas.get(key).toString());
            }

            stamper.setFormFlattening(true); // 这个必须设
            stamper.close();

            // 创建一个pdf实例
            Document document = new Document();
            PdfCopy copy = new PdfCopy(document, os);
            document.open();
            PdfImportedPage importedPage = copy.getImportedPage(new PdfReader(baos.toByteArray()), 1);
            copy.addPage(importedPage);
            document.close(); // open和close一套

            // 强制下载
            //response.reset();
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment;fileName="
                    + URLEncoder.encode(filename, "UTF-8"));

        } catch (IOException | DocumentException e) {
            e.printStackTrace();
        } finally { // 最后一定要关闭流
            try {
                baos.close();
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return CommonResult.buildR(Status.OK,"打印成功");
    }

}
